/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package util.www.sql;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import util.StringUtil;
import util.form.ValorObject;

/**
 *
 * @author Rdelacruz
 * @version 2014.12.18
 */
public class WhereSql {

    protected final StringBuilder sb = new StringBuilder();
    
    private final String AND = " and ";
    private final String OR = " or ";
    
    private Map<Integer,String> parametros = new HashMap<Integer,String>(); 
    
    public WhereSql and(final String prefijo, final ValorObject valorObject) throws SQLException {
        String valor = valorObject.toString();
    	if(valorObject.getClaseValor()==String.class) {
            agregar(AND,prefijo,valor);
    	}
    	else {
            agregarCondicion(AND,prefijo+valor,valor);
    	}
    	return this;
    }
    
    public WhereSql and(final String condicion) throws SQLException {
        agregarCondicion(AND,condicion,condicion);
        return this;
    }
    
    public WhereSql and(final String prefijo, final String valor) throws SQLException {
        agregar(AND,prefijo,valor);
        return this;
    }
    
    public WhereSql and(final String prefijo, final String[] valores) throws SQLException {
        agregar(AND,prefijo,valores);
        return this;
    }
    
    public WhereSql and(final String prefijo, final Integer valor) throws SQLException {
        agregar(AND,prefijo,valor);
        return this;
    }
    
    public WhereSql and(final WhereSql w) throws SQLException {
        agregar(AND,w);
        return this;
    }
    
    public WhereSql or(final String condicion) throws SQLException {
        agregarCondicion(OR,condicion,condicion);
        return this;
    }
    
    public WhereSql or(final String prefijo, final String valor) throws SQLException {
        agregar(OR,prefijo,valor);
        return this;
    }
    
    public WhereSql or(final String prefijo, final String[] valores) throws SQLException {
        agregar(OR,prefijo,valores);
        return this;
    }
    
    public WhereSql or(final String prefijo, final Integer valor) throws SQLException {
        agregar(OR,prefijo,valor);
        return this;
    }
    
    public WhereSql or(final WhereSql w) throws SQLException {
        agregar(OR,w);
        return this;
    }
    
    public boolean isEmpty() {
        return sb.length()==0; 
    }
    
    private void agregar(final String operador, final WhereSql w) throws SQLException {        
        String valor = w.sb.toString();
        String condicion = "("+valor+")";
        agregarCondicion(operador,condicion,valor);
    }
        
    private void agregar(final String operador, final String prefijo, final String[] valores) throws SQLException {
        if(valores!=null && valores.length>0) {
            StringBuilder sbValor = new StringBuilder();
            sbValor.append("(");
            for(String v:valores) {
                sbValor.append("'");
                sbValor.append(v);
                sbValor.append("'");
                sbValor.append(",");
            }            
            sbValor.deleteCharAt(sbValor.length()-1);//borrando ultima coma
            sbValor.append(")");
            
            String valor = sbValor.toString();
            agregarCondicion(operador,prefijo+valor,valor);
        }
    }
        
    private void agregar(final String operador, final String prefijo, final String valor) throws SQLException {
        agregarCondicion(operador,prefijo+"'"+valor+"'",valor);       
    }
    
    private void agregar(final String operador, final String prefijo, final Integer valor) throws SQLException {
        agregarCondicion(operador,prefijo+valor, (valor==null? null : valor+"") );
    }
    
    private void agregarCondicion(final String operador, final String condicion, final String valor) throws SQLException {
        if(valor==null || valor.trim().isEmpty()) {
            if(lanzarExcepcion())
                throw new SQLException("Condición inválida: "+condicion+".");
        }
        else {
            if(sb.length()>0)
                sb.append(operador);
            sb.append(condicion);                
        }
    }    
    
    public final String getSql() {
        if(sb.length()>0) {
        	String texto = sb.toString();       	
        	if(!parametros.isEmpty()) {
        		texto = StringUtil.replaceParameters(texto, parametros);
        	}        	
            return " where "+texto;
        }
        return "";
    }

    protected boolean lanzarExcepcion() {
        return true;
    }  
    
    public void setParametro(int nroParametro, String valor) {
    	parametros.put(nroParametro, "'"+valor+"'");
    }
    
    public void setParametro(int nroParametro, Integer valor) {
    	parametros.put(nroParametro, valor+"");
    }
}
